package retina;

public class Ganglion 
{
	private Photoreceptor[][] receptorField;
	private final double centerWeight;
	
	public static final Integer ON_CENTER = 1;
	public static final Integer OFF_CENTER = 2;
	
	public Ganglion(int width)
	{
		if (width%2 != 1) throw new java.lang.ArrayIndexOutOfBoundsException("Non-odd Size");
		
		receptorField = new Photoreceptor[width][width];
		
		centerWeight = 1.00;
	}
	
	public Ganglion(int width, double centerWeight)
	{
		if (width%2 != 1) throw new java.lang.ArrayIndexOutOfBoundsException("Non-odd Size");
		
		receptorField = new Photoreceptor[width][width];
		
		this.centerWeight = centerWeight;
	}
	
	public void initialize(Object params)
	{
		//Default: all excitatory
		if(params == null)
		{
			for (Photoreceptor[] row : receptorField)
			{
				for (Photoreceptor receptor : row)
				{
					receptor = new Photoreceptor();
				}
			}
		}
		
		if (params instanceof Integer)
		{
			Integer receptorFieldType = (Integer) params;
			
			int centerIndex = (int) receptorField.length/2;
			
			for (int x = 0; x < receptorField.length; x++)
			{
				for (int y = 0; y < receptorField[x].length; y++)
				{
					
					if (receptorFieldType == Ganglion.ON_CENTER)
					{
						if (y == centerIndex && x == centerIndex) receptorField[x][y] = new Photoreceptor(false);
						else receptorField[x][y] = new Photoreceptor(true);
					}
					else if (receptorFieldType == Ganglion.OFF_CENTER)
					{
						if (y == centerIndex && x == centerIndex) receptorField[x][y] = new Photoreceptor(true);
						else receptorField[x][y] = new Photoreceptor(false);
					}
				}
			}
		}
	}
	
	//Process inputs from photoreceptors ONLY
	public double fire(double[][] inputs)
	{
		double cumulativeFiring = 0;
		int centerIndex = (int) receptorField.length/2;
		
		for (int x = 0; x < inputs.length; x++)
		{
			for (int y = 0; y < inputs[x].length; y++)
			{
				if (y == centerIndex && x == centerIndex) cumulativeFiring += centerWeight*inputs[x][y];
				else cumulativeFiring += inputs[x][y];
			}
		}
		
		return cumulativeFiring;
	}
	
	
	//TODO Remove, externalize to container class
	public double firePhotoreceptor(double input, int x, int y)
	{
		return this.receptorField[x][y].fire(input);
	}
	
	public void crudePrint()
	{
		for (int x = 0; x < this.receptorField.length; x++)
		{
			System.out.println();
			for (int y = 0; y < this.receptorField[x].length; y++)
			{
				System.out.print( (receptorField[x][y].isInhibitor()) ? "0 ":"1 " );
			}
		}
	}
}
